//Nitin's testing project info
/*var projects = [
					{'ws' : '4366145736', 'proj' : '3834920364', 'rel' : 'Release 1', 'projName' : 'ABC'},
					{'ws' : '4366145736', 'proj' : '3834920584', 'rel' : 'Release 1.1', 'projName' : 'XYZ'}
				];
*/

function init(){
	reduceAsync(projects, generateRequirementQuery, processRallyRequirements);
	//reduceAsync(projects, generateReleaseQuery, processRallyReleases);
}

function reduceAsync(arr, genQryFn, proceedFn, res){
	if (!res)
		res = [];
	var fst = _.first(arr);
	var qObj = genQryFn(fst);
	qObj.ds.findAll(qObj.qry, function(results){
									//res.push(results.out);
									res.push({'name' : fst.projName, 'resArr' : results.out});
									var lst = _.rest(arr);
									if (lst.length) //if array has some values remaining
										reduceAsync(lst, genQryFn, proceedFn, res);
									else
										proceedFn(res);
								});
}

function processRallyReleases(results){
	//console.log(results);
	results = _.map(results, function(e){
								return {
									'name' : e.name,
									'resArr' : _.map(e.resArr, function(x){
																	return x.Name;
																})
								};
							});
	console.log(results);
}

function generateReleaseQuery(arrVal){
	var retVal = {};
	retVal.ds = new rally.sdk.data.RallyDataSource(arrVal.ws, 
												   arrVal.proj,  
												   '__PROJECT_SCOPING_UP__', 
												   '__PROJECT_SCOPING_DOWN__');
	var queryConfig = [];
	//var reqsQuery = rally.sdk.util.Query('CFURType  = "Requirement"').and('Release.Name  = "Release 1"').and('Iteration.Name  = "Iteration 1"');
	//var reqsQuery = rally.sdk.util.Query('Release.Name  = "'+ arrVal.rel +'"');
	queryConfig[0] = {  
                key: 'out',  
                type: 'Release',
				//query: reqsQuery,
                fetch: 'Name'
            };
	retVal.qry = queryConfig;
	
	return retVal;
}

function generateRequirementQuery(arrVal){
	var retVal = {};
	retVal.ds = new rally.sdk.data.RallyDataSource(arrVal.ws, 
												   arrVal.proj,  
												   '__PROJECT_SCOPING_UP__', 
												   '__PROJECT_SCOPING_DOWN__');
	var queryConfig = [];
	//var reqsQuery = rally.sdk.util.Query('CFURType  = "Requirement"').and('Release.Name  = "Release 1"').and('Iteration.Name  = "Iteration 1"');
	var reqsQuery = rally.sdk.util.Query('Release.Name  = "'+ arrVal.rel +'"');
	queryConfig[0] = {  
                key: 'out',  
                type: 'HierarchicalRequirement',
				query: reqsQuery,
                fetch: 'FormattedID,CFURType,ScheduleState,Status,Release'
            };
	retVal.qry = queryConfig;
	
	return retVal;
}

function processRallyRequirements(results){
	//console.log(results);
	var templateFn = _.template("<div><h2><%= heading %></h2><div id='<%= headingId %>'></div></div>");

	_.each(results, function (e){
						tabulatedDisplay(e.name, e.resArr, templateFn);
					});
}


function tabulatedDisplay(name, results, templateFn){
	var matchFnArr = [matchFn('User Story', 'Defined'),
						matchFn('User Story', 'In-Progress'),
						matchFn('User Story', 'Completed'),
						matchFn('User Story', 'Accepted'),
						matchFn('User Story', 'Released')//,
						//matchFn('Requirement', 'Defined'),
						//matchFn('Requirement', 'In-Progress'),
						//matchFn('Requirement', 'Completed'),
						//matchFn('Requirement', 'Accepted'),
						//matchFn('Requirement', 'Released')
					 ];
	var matchResults = _.map(results, function(v){
											return checkMatches(matchFnArr, v);
										});
	//console.log(matchResults);
	var summary = summarize(_.compact(_.flatten(matchResults)));
	//console.log(summary);
	
	//console.log("setting table config");
	var tableConfig = {'columns' : [{'key' : 'label', 'header' : ' ', 'width' : 300}, {'key' : 'value', 'header' : 'Count', 'width' : 100}],
					   'items' : summary,
					   'sortingEnabled' : true
						};
	//console.log("creating new table");
	var table = new rally.sdk.ui.Table(tableConfig);
	//table.display($j('#cntnt').get(0));
	
	//console.log("cleaning name");
	var cleanedName = name.replace(/[ .()]/g,"");
	//console.log("setting divs");
	$j('#cntnt').append(templateFn({'heading' : name, 'headingId': cleanedName}));
	//console.log("setting table");
	table.display($j('#'+cleanedName).get(0));
	//console.log("done");
}

function matchFn(val1, val2){
	return function(obj){
		//if(obj.CFURType == val1 && obj.ScheduleState == val2) THIS SHOULD BE PUT IN PLACE WHEN CFUR TYPE IS CORRECTED
		if(obj.ScheduleState == val2)
			return val1 + " " + val2;
		else return null;
	}
}

function checkMatches(matchFns, obj){
	return _.map(matchFns, 
				 function(fn){
					return fn(obj);
				 });
}

function summarize(results){
	//console.log("in summarize");
	//console.log(results);
	var summary = {};
	var increment = function (val){
						if (val)
							return val + 1;
						else return 1;
					};
	_.map(results, function(result){
								upsert(summary, result, increment);
								return 0;
							});
	summary = _.map(summary, function(v, k){
											return {'label' : k, 'value' : v};
										});
	return _.sortBy(summary, 'label');
}